/*!
 * \file CliquerGoloso.cpp
 *
 * \date Jan 31, 2014
 * \author correa
 */

#include <CliquerGoloso.h>

CliquerGoloso::CliquerGoloso(const Grafo& g, const Grafo &ord, bool clqOrStab) :
	_n(g.getN()), _grafo(g), _RR(clqOrStab ? *(new VertexSet(_n)) : getComplParamSet(_n)),
	_compGrados({&ord}),	_suborden(new Lista(_n))
{
}

CliquerGoloso::~CliquerGoloso()
{
	delete &_RR;
	delete _suborden;
}

int CliquerGoloso::optimize(const VertexSet& subgrafo, ProjectableCliqueSet& clique,
		int cotaInferior, int cotaSuperior, int tolerancia)
{
	int size = 0, v;
	_RR.copyAll(subgrafo);

	_suborden->clear();
	subgrafo.lista(*_suborden);
	sort(_suborden->begin(), _suborden->end(), _compGrados);

	for (int i = 0; i < _suborden->cantidad(); i++) {
		v = (*_suborden)[i];
		if (_RR.contains(v))
		{
			clique.add(v);
			size++;
			// note that vidx remains in _RR only if clqOrStab=false
			_RR.retainAll(_grafo.vecinos(v));
			_RR.remove(v);
		}
	}

	return size;
}

int CliquerGoloso::optimize(const IntValueArray& pesos, const VertexSet& subgrafo,
		ProjectableCliqueSet& clique, int cotaInferior, int cotaSuperior,
		int tolerancia)
{
	int weight = 0;
	int v;
	_RR.copyAll(subgrafo);

	_suborden->clear();
	_RR.lista(*_suborden);
	_pesosInt._comparray = &pesos;
	sort(_suborden->begin(), _suborden->end(), _pesosInt);

	for (int i = 0; i < _suborden->cantidad(); i++) {
		v = (*_suborden)[i];
		if (_RR.contains(v))
		{
			clique.add(v, pesos[v]);
			weight+=pesos[v];
			// note that vidx remains in _RR only if clqOrStab=false
			_RR.retainAll(_grafo.vecinos(v));
			_RR.remove(v);
		}
	}

	return weight;
}

double CliquerGoloso::optimize(const DoubleValueArray& pesos, const VertexSet& subgrafo,
		ProjectableCliqueSet& clique, double cotaInferior, double cotaSuperior,
		double tolerancia)
{
	double weight = 0.0;
	int v;
	_RR.copyAll(subgrafo);

	_suborden->clear();
	_RR.lista(*_suborden);
	_pesosDbl._comparray = &pesos;
	sort(_suborden->begin(), _suborden->end(), _pesosDbl);

	for (int i = 0; i < _suborden->cantidad(); i++) {
		v = (*_suborden)[i];
		if (_RR.contains(v))
		{
			clique.add(v, pesos[v]);
			weight+=pesos[v];
			// note that vidx remains in _RR only if clqOrStab=false
			_RR.retainAll(_grafo.vecinos(v));
			_RR.remove(v);
		}
	}

	return weight;
}
